just go ahead and flush all the first validate stuff if it hasn't been
authorHavoc Pennington <hp@redhat.com>
Wed, 13 Feb 2002 23:44:03 +0000 (23:44 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Wed, 13 Feb 2002 23:44:03 +0000 (23:44 +0000)
2002-02-13  Havoc Pennington  <hp@redhat.com>

* gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush
all the first validate stuff if it hasn't been done, presumably
someone called process_updates at a weird time.

* tests/testtext.c (do_apply_colors): terminate on >= end, not >
end, avoids infinite loop when end is at the end of the buffer.

* gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
line data, we were adding it to the wrong line ("line" instead of
"start_line")

13 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtktextbtree.c
gtk/gtktextbtree.h
gtk/gtktextbuffer.c
gtk/gtktextlayout.c
gtk/gtktextview.c
tests/testtext.c

index 3be78ccf6508cf0453da268b991aa2d01a3f64fb..91483566a33b6b4a1e2f1fac0b826bff3ca5a5c8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2002-02-13  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush 
+       all the first validate stuff if it hasn't been done, presumably
+       someone called process_updates at a weird time.
+
+       * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+       end, avoids infinite loop when end is at the end of the buffer.
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+       line data, we were adding it to the wrong line ("line" instead of
+       "start_line")
+
 2002-02-13  Joe Shaw  <joe@ximian.com>
 
        * gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
index 3be78ccf6508cf0453da268b991aa2d01a3f64fb..91483566a33b6b4a1e2f1fac0b826bff3ca5a5c8 100644 (file)
@@ -1,3 +1,16 @@
+2002-02-13  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush 
+       all the first validate stuff if it hasn't been done, presumably
+       someone called process_updates at a weird time.
+
+       * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+       end, avoids infinite loop when end is at the end of the buffer.
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+       line data, we were adding it to the wrong line ("line" instead of
+       "start_line")
+
 2002-02-13  Joe Shaw  <joe@ximian.com>
 
        * gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
index 3be78ccf6508cf0453da268b991aa2d01a3f64fb..91483566a33b6b4a1e2f1fac0b826bff3ca5a5c8 100644 (file)
@@ -1,3 +1,16 @@
+2002-02-13  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush 
+       all the first validate stuff if it hasn't been done, presumably
+       someone called process_updates at a weird time.
+
+       * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+       end, avoids infinite loop when end is at the end of the buffer.
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+       line data, we were adding it to the wrong line ("line" instead of
+       "start_line")
+
 2002-02-13  Joe Shaw  <joe@ximian.com>
 
        * gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
index 3be78ccf6508cf0453da268b991aa2d01a3f64fb..91483566a33b6b4a1e2f1fac0b826bff3ca5a5c8 100644 (file)
@@ -1,3 +1,16 @@
+2002-02-13  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush 
+       all the first validate stuff if it hasn't been done, presumably
+       someone called process_updates at a weird time.
+
+       * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+       end, avoids infinite loop when end is at the end of the buffer.
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+       line data, we were adding it to the wrong line ("line" instead of
+       "start_line")
+
 2002-02-13  Joe Shaw  <joe@ximian.com>
 
        * gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
index 3be78ccf6508cf0453da268b991aa2d01a3f64fb..91483566a33b6b4a1e2f1fac0b826bff3ca5a5c8 100644 (file)
@@ -1,3 +1,16 @@
+2002-02-13  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush 
+       all the first validate stuff if it hasn't been done, presumably
+       someone called process_updates at a weird time.
+
+       * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+       end, avoids infinite loop when end is at the end of the buffer.
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+       line data, we were adding it to the wrong line ("line" instead of
+       "start_line")
+
 2002-02-13  Joe Shaw  <joe@ximian.com>
 
        * gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
index 3be78ccf6508cf0453da268b991aa2d01a3f64fb..91483566a33b6b4a1e2f1fac0b826bff3ca5a5c8 100644 (file)
@@ -1,3 +1,16 @@
+2002-02-13  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush 
+       all the first validate stuff if it hasn't been done, presumably
+       someone called process_updates at a weird time.
+
+       * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+       end, avoids infinite loop when end is at the end of the buffer.
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+       line data, we were adding it to the wrong line ("line" instead of
+       "start_line")
+
 2002-02-13  Joe Shaw  <joe@ximian.com>
 
        * gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
index 3be78ccf6508cf0453da268b991aa2d01a3f64fb..91483566a33b6b4a1e2f1fac0b826bff3ca5a5c8 100644 (file)
@@ -1,3 +1,16 @@
+2002-02-13  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtktextview.c (gtk_text_view_paint): just go ahead and flush 
+       all the first validate stuff if it hasn't been done, presumably
+       someone called process_updates at a weird time.
+
+       * tests/testtext.c (do_apply_colors): terminate on >= end, not >
+       end, avoids infinite loop when end is at the end of the buffer.
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_delete): when creating a
+       line data, we were adding it to the wrong line ("line" instead of
+       "start_line")
+
 2002-02-13  Joe Shaw  <joe@ximian.com>
 
        * gtk/gtktreeitem.c (gtk_tree_item_expose): Don't chain up to the
index 5f00fc088f94afd8986c45ba6ce41c107510d596..fa5aeb095fca130f6bf0d7a7aedfd2a2e21c67a7 100644 (file)
@@ -575,6 +575,7 @@ _gtk_text_btree_delete (GtkTextIter *start,
     _gtk_text_btree_check (tree);
   
   /* Broadcast the need for redisplay before we break the iterators */
+  DV (g_print ("invalidating due to deleting some text (%s)\n", G_STRLOC));
   _gtk_text_btree_invalidate_region (tree, start, end);
 
   /* Save the byte offset so we can reset the iterators */
@@ -826,8 +827,8 @@ _gtk_text_btree_delete (GtkTextIter *start,
                    * we do need to store our temporary sizes. So we
                    * create the line data and assume a line w/h of 0.
                    */
-                  ld = _gtk_text_line_data_new (view->layout, line);
-                  _gtk_text_line_add_data (line, ld);
+                  ld = _gtk_text_line_data_new (view->layout, start_line);
+                  _gtk_text_line_add_data (start_line, ld);
                   ld->width = 0;
                   ld->height = 0;
                   ld->valid = FALSE;
@@ -1033,6 +1034,7 @@ _gtk_text_btree_insert (GtkTextIter *iter,
        above. FIXME */
     gtk_text_iter_forward_chars (&end, char_count_delta);
 
+    DV (g_print ("invalidating due to inserting some text (%s)\n", G_STRLOC));
     _gtk_text_btree_invalidate_region (tree,
                                       &start, &end);
 
@@ -1081,6 +1083,7 @@ insert_pixbuf_or_widget_segment (GtkTextIter        *iter,
   *iter = start;
   gtk_text_iter_forward_char (iter); /* skip forward past the segment */
 
+  DV (g_print ("invalidating due to inserting pixbuf/widget (%s)\n", G_STRLOC));
   _gtk_text_btree_invalidate_region (tree, &start, iter);
 }
      
@@ -1414,9 +1417,9 @@ _gtk_text_btree_remove_view (GtkTextBTree *tree,
 }
 
 void
-_gtk_text_btree_invalidate_region (GtkTextBTree *tree,
-                                  const GtkTextIter *start,
-                                  const GtkTextIter *end)
+_gtk_text_btree_invalidate_region (GtkTextBTree      *tree,
+                                   const GtkTextIter *start,
+                                   const GtkTextIter *end)
 {
   BTreeView *view;
 
@@ -1526,6 +1529,7 @@ queue_tag_redisplay (GtkTextBTree      *tree,
 {
   if (_gtk_text_tag_affects_size (tag))
     {
+      DV (g_print ("invalidating due to size-affecting tag (%s)\n", G_STRLOC));
       _gtk_text_btree_invalidate_region (tree, start, end);
     }
   else if (_gtk_text_tag_affects_nonsize_appearance (tag))
@@ -2448,6 +2452,7 @@ redisplay_mark (GtkTextLineSegment *mark)
   end = iter;
   gtk_text_iter_forward_char (&end);
 
+  DV (g_print ("invalidating due to moving visible mark (%s)\n", G_STRLOC));
   _gtk_text_btree_invalidate_region (mark->body.mark.tree,
                                     &iter, &end);
 }
@@ -5411,6 +5416,7 @@ tag_changed_cb (GtkTextTagTable *table,
         {
           /* Must be a last toggle if there was a first one. */
           _gtk_text_btree_get_iter_at_last_toggle (tree, &end, tag);
+          DV (g_print ("invalidating due to tag change (%s)\n", G_STRLOC));
           _gtk_text_btree_invalidate_region (tree,
                                             &start, &end);
 
index b3ae5fb93fdfca5435ad5be8f2f27587f748b5c8..dea958ec371e8d5a17436b12453eefbfa5086eb2 100644 (file)
@@ -1,6 +1,16 @@
 #ifndef GTK_TEXT_BTREE_H
 #define GTK_TEXT_BTREE_H
 
+#if 0
+#define DEBUG_VALIDATION_AND_SCROLLING
+#endif
+
+#ifdef DEBUG_VALIDATION_AND_SCROLLING
+#define DV(x) (x)
+#else
+#define DV(x)
+#endif
+
 #include <gtk/gtktextbuffer.h>
 #include <gtk/gtktexttag.h>
 #include <gtk/gtktextmark.h>
index 7650d41e2ac29a9634c0968924edad7f58bd1147..63a7f68883cf852670d0b67be0948d52d0115487 100644 (file)
@@ -850,6 +850,15 @@ gtk_text_buffer_real_insert_range (GtkTextBuffer     *buffer,
   range_start = start;
   range_end = start;
 
+
+  /* FIXME if you insert a range into itself, this can loop infinitely because
+   * the region being copied keeps growing as we insert. The fix is probably to create a
+   * copy of what's being inserted, or to save two regions, the region before
+   * the insertion point and the region after.
+   * 
+   * http://bugzilla.gnome.org/show_bug.cgi?id=71412
+   */
+  
   while (TRUE)
     {
       gint start_offset;
index 806d147f32165b77c3e9871c41fa810a92539083..15358c95e92729a7fe392e37013db4621b46355e 100644 (file)
@@ -293,6 +293,7 @@ gtk_text_layout_default_style_changed (GtkTextLayout *layout)
 {
   g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
 
+  DV (g_print ("invalidating all due to default style change (%s)\n", G_STRLOC));
   gtk_text_layout_invalidate_all (layout);
 }
 
@@ -335,6 +336,7 @@ gtk_text_layout_set_contexts (GtkTextLayout *layout,
   layout->rtl_context = rtl_context;
   g_object_ref (G_OBJECT (rtl_context));
 
+  DV (g_print ("invalidating all due to new pango contexts (%s)\n", G_STRLOC));
   gtk_text_layout_invalidate_all (layout);
 }
 
@@ -391,6 +393,7 @@ gtk_text_layout_set_screen_width (GtkTextLayout *layout, gint width)
 
   layout->screen_width = width;
 
+  DV (g_print ("invalidating all due to new screen width (%s)\n", G_STRLOC));
   gtk_text_layout_invalidate_all (layout);
 }
 
@@ -919,7 +922,8 @@ gtk_text_layout_real_wrap (GtkTextLayout   *layout,
   GtkTextLineDisplay *display;
 
   g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), NULL);
-
+  g_return_val_if_fail (line != NULL, NULL);
+  
   if (line_data == NULL)
     {
       line_data = _gtk_text_line_data_new (layout, line);
index ceb9987d67cb930385139c291e84e638561133c2..77b99bbe6aab1ca35f42655d1956cdf48e28ec74 100644 (file)
@@ -82,9 +82,6 @@
  *
  */
 
-#define SCREEN_WIDTH(widget) text_window_get_width (GTK_TEXT_VIEW (widget)->text_window)
-#define SCREEN_HEIGHT(widget) text_window_get_height (GTK_TEXT_VIEW (widget)->text_window)
-
 #if 0
 #define DEBUG_VALIDATION_AND_SCROLLING
 #endif
@@ -95,6 +92,9 @@
 #define DV(x)
 #endif
 
+#define SCREEN_WIDTH(widget) text_window_get_width (GTK_TEXT_VIEW (widget)->text_window)
+#define SCREEN_HEIGHT(widget) text_window_get_height (GTK_TEXT_VIEW (widget)->text_window)
+
 struct _GtkTextPendingScroll
 {
   GtkTextMark   *mark;
@@ -312,9 +312,10 @@ static void gtk_text_view_queue_scroll           (GtkTextView   *text_view,
                                                   gdouble        xalign,
                                                   gdouble        yalign);
 
-static gboolean gtk_text_view_flush_scroll       (GtkTextView *text_view);
-static void     gtk_text_view_update_adjustments (GtkTextView *text_view);
-static void     gtk_text_view_invalidate         (GtkTextView *text_view);
+static gboolean gtk_text_view_flush_scroll         (GtkTextView *text_view);
+static void     gtk_text_view_update_adjustments   (GtkTextView *text_view);
+static void     gtk_text_view_invalidate           (GtkTextView *text_view);
+static void     gtk_text_view_flush_first_validate (GtkTextView *text_view);
 
 static void gtk_text_view_update_im_spot_location (GtkTextView *text_view);
 
@@ -1146,7 +1147,8 @@ gtk_text_view_set_buffer (GtkTextView   *text_view,
   
   if (GTK_WIDGET_VISIBLE (text_view))
     gtk_widget_queue_draw (GTK_WIDGET (text_view));
-  
+
+  DV(g_print ("Invalidating due to set_buffer\n"));
   gtk_text_view_invalidate (text_view);
 }
 
@@ -1547,7 +1549,10 @@ gtk_text_view_flush_scroll (GtkTextView *text_view)
   DV(g_print(G_STRLOC"\n"));
   
   if (text_view->pending_scroll == NULL)
-    return FALSE;
+    {
+      DV (g_print ("in flush scroll, no pending scroll\n"));
+      return FALSE;
+    }
 
   scroll = text_view->pending_scroll;
 
@@ -2365,6 +2370,7 @@ gtk_text_view_remove_validate_idles (GtkTextView *text_view)
 {
   if (text_view->first_validate_idle != 0)
     {
+      DV (g_print ("Removing first validate idle: %s\n", G_STRLOC));
       g_source_remove (text_view->first_validate_idle);
       text_view->first_validate_idle = 0;
     }
@@ -2938,19 +2944,11 @@ gtk_text_view_size_allocate (GtkWidget *widget,
   if (yoffset_changed)
     gtk_adjustment_value_changed (vadj);
 
-  if (text_view->first_validate_idle != 0)
-    {
-      /* The GTK resize loop processes all the pending exposes right
-       * after doing the resize stuff, so the idle sizer won't have a
-       * chance to run. So we do the work here. 
-       */
-
-      g_source_remove (text_view->first_validate_idle);
-      text_view->first_validate_idle = 0;
-      
-      if (!gtk_text_view_flush_scroll (text_view))
-        gtk_text_view_validate_onscreen (text_view);
-    }
+  /* The GTK resize loop processes all the pending exposes right
+   * after doing the resize stuff, so the idle sizer won't have a
+   * chance to run. So we do the work here. 
+   */
+  gtk_text_view_flush_first_validate (text_view);
 
   /* widget->window doesn't get auto-redrawn as the layout is computed, so has to
    * be invalidated
@@ -3004,23 +3002,18 @@ gtk_text_view_validate_onscreen (GtkTextView *text_view)
   g_assert (text_view->onscreen_validated);
 }
 
-static gboolean
-first_validate_callback (gpointer data)
+static void
+gtk_text_view_flush_first_validate (GtkTextView *text_view)
 {
-  GtkTextView *text_view = data;
-
-  GDK_THREADS_ENTER ();
-  
-  /* Note that some of this code is duplicated at the end of size_allocate,
-   * keep in sync with that.
-   */
-  
-  DV(g_print(G_STRLOC"\n"));
+  if (text_view->first_validate_idle == 0)
+    return;
 
   /* Do this first, which means that if an "invalidate"
    * occurs during any of this process, a new first_validate_callback
    * will be installed, and we'll start again.
    */
+  DV (g_print ("removing first validate in %s\n", G_STRLOC));
+  g_source_remove (text_view->first_validate_idle);
   text_view->first_validate_idle = 0;
   
   /* be sure we have up-to-date screen size set on the
@@ -3047,8 +3040,23 @@ first_validate_callback (gpointer data)
       DV(g_print(">Leaving first validate idle ("G_STRLOC")\n"));
       
       g_assert (text_view->onscreen_validated);
-      
     }
+}
+
+static gboolean
+first_validate_callback (gpointer data)
+{
+  GtkTextView *text_view = data;
+
+  GDK_THREADS_ENTER ();
+  
+  /* Note that some of this code is duplicated at the end of size_allocate,
+   * keep in sync with that.
+   */
+  
+  DV(g_print(G_STRLOC"\n"));
+
+  gtk_text_view_flush_first_validate (text_view);
   
   GDK_THREADS_LEAVE ();
   
@@ -3082,11 +3090,12 @@ incremental_validate_callback (gpointer data)
 
 static void
 gtk_text_view_invalidate (GtkTextView *text_view)
-{
+{  
+  DV (g_print (">Invalidate, onscreen_validated = %d now FALSE ("G_STRLOC")\n",
+               text_view->onscreen_validated));
+
   text_view->onscreen_validated = FALSE;
   
-  DV(g_print(">Invalidate, onscreen_validated = FALSE ("G_STRLOC")\n"));
-  
   if (!text_view->first_validate_idle)
     {
       text_view->first_validate_idle = g_idle_add_full (GTK_PRIORITY_RESIZE - 2, first_validate_callback, text_view, NULL);
@@ -3110,6 +3119,7 @@ invalidated_handler (GtkTextLayout *layout,
 
   text_view = GTK_TEXT_VIEW (data);
 
+  DV (g_print ("Invalidating due to layout invalidate signal\n"));
   gtk_text_view_invalidate (text_view);
 }
 
@@ -3205,7 +3215,10 @@ changed_handler (GtkTextLayout     *layout,
         }
 
       if (yoffset_changed)
-        gtk_adjustment_value_changed (get_vadjustment (text_view));
+        {
+          DV(g_print ("Changing scroll position (%s)\n", G_STRLOC));
+          gtk_adjustment_value_changed (get_vadjustment (text_view));
+        }
 
       /* FIXME be smarter about which anchored widgets we update */
 
@@ -4007,19 +4020,37 @@ gtk_text_view_paint (GtkWidget      *widget,
   GtkTextView *text_view;
   GList *child_exposes;
   GList *tmp_list;
+  GdkRegion *updates;
   
   text_view = GTK_TEXT_VIEW (widget);
 
   g_return_if_fail (text_view->layout != NULL);
   g_return_if_fail (text_view->xoffset >= 0);
   g_return_if_fail (text_view->yoffset >= 0);
-  
-  DV (g_print (G_STRLOC": first_validate_idle: %d\n",
-               text_view->first_validate_idle));
+
+  while (text_view->first_validate_idle != 0)
+    {
+      DV (g_print (G_STRLOC": first_validate_idle: %d\n",
+                   text_view->first_validate_idle));
+      gtk_text_view_flush_first_validate (text_view);
+    }
+
+  /* More regions could have become invalid in the above loop */
+  updates = gdk_window_get_update_area (text_view->text_window->bin_window);
+  if (updates)
+    {
+      GdkRectangle rect;
+      
+      gdk_region_get_clipbox (updates, &rect);
+
+      gdk_rectangle_union (area, &rect, area);
+      
+      gdk_region_destroy (updates);
+    }
   
   if (!text_view->onscreen_validated)
     {
-      g_warning (G_STRLOC ": somehow some text lines were modified or scrolling occurred since the last validation of lines on the screen - this is a known bug, no need to report.");
+      g_warning (G_STRLOC ": somehow some text lines were modified or scrolling occurred since the last validation of lines on the screen - may be a text widget bug.");
       G_BREAKPOINT ();
     }
   
@@ -4957,6 +4988,7 @@ move_mark_to_pointer_and_scroll (GtkTextView *text_view,
     GtkTextMark *mark =
       gtk_text_buffer_get_mark (get_buffer (text_view), mark_name);
 
+    /* This may invalidate the layout */
     DV(g_print (G_STRLOC": move mark\n"));
     gtk_text_buffer_move_mark (get_buffer (text_view),
                                mark,
@@ -4965,6 +4997,9 @@ move_mark_to_pointer_and_scroll (GtkTextView *text_view,
     DV(g_print (G_STRLOC": scrolling onscreen\n"));
     gtk_text_view_scroll_mark_onscreen (text_view, mark);
   }
+
+  DV (g_print ("first validate idle leaving %s is %d\n",
+               G_STRLOC, text_view->first_validate_idle));
 }
 
 static gint
@@ -5865,6 +5900,8 @@ gtk_text_view_value_changed (GtkAdjustment *adj,
   /* process exposes */
   if (GTK_WIDGET_REALIZED (text_view))
     {
+      DV (g_print ("Processing updates (%s)", G_STRLOC));
+      
       if (text_view->left_window)
         gdk_window_process_updates (text_view->left_window->bin_window, TRUE);
 
index e153fe204f4d1236334a1b41a980ecd04682fe2d..e9c67dc22db5cff14bb25b95ea28a497fdb610bc 100644 (file)
@@ -1086,7 +1086,7 @@ do_apply_colors (gpointer callback_data,
               gtk_text_iter_forward_char (&next);
               gtk_text_iter_forward_char (&next);
 
-              if (gtk_text_iter_compare (&next, &end) > 0)
+              if (gtk_text_iter_compare (&next, &end) >= 0)
                 {
                   next = end;
                   done = TRUE;